TechNote - Styles
Thursday, February 16, 2023
12:52 PM
This is a discussion of font styles as they pertain to the desktop edition of OneNote.
First, a couple of definitions for clarity. I try to hold true to these definitions throughout the article.
- An attribute always refers to an attribute of an XML element.
- A property always refers to the individual properties of a style.
In this following example, a span element has a style attribute and that attribute includes a number of style properties, specifically font-style and color.
<span style='font-style:italic;color:#C55A11'>
What is the Page XML Model?
The OneNote user interface presents and lets you manage a logical view of objects known as notebooks, sections, and pages. (Section groups are really those just logical folders within a section.) Thre phyisical storage model is slightly different: a new section.one file is maintained for each section and that section.one file contains data for all pages in that section. Similarly, a new notebook.onetoc2 file is maintained for each notebook and that notebook.onetoc2 file constains an index of all sections in that notebook.
The section.one files are binary files with a complicated object model defined here. While it is possible to write a program to read and write these files directly, that becomes problematic when these files are stored on OneDrive where they're not so easily accessible.
So instead, Microsoft developed a public library (a DLL) that allows third-parties to develop add-ins for OneNote. (In fact, there are libraries for every Office product and their corresponding add-ins.) And instead of exposing the binary object models stored in the .one files, the library transforms those models into a logical XML representation to make it more readily consumable by most common programming frameworks. This XML is fully described by the OneNote Application XSD schema definition file.
We'll explore the logical XML representation of a page; we will not touch upon the physical storage model at all. But it's important to remember that the XML is not how the page is actually stored - it is just a representation or transformation or projection of the physical models and may not map one-to-one to how those physical models are stored.
Page XML
Here is the smallest possible XML representation of a OneNote page as returned by the IApplication.GetPageContent method. This does not have a one:Title block because it was created as a QuickNote, and all extraneous attributes have been removed, both for simplicity.
As we explore how OneNote applies styles to a page, we'll keep track of the changes in the two areas outlined below.
<one:Page>
<one:QuickStyleDef
index="0" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri"
fontSize="11.0" spaceBefore="0.0" spaceAfter="0.0" />
<one:PageSettings RTL="false" color="#FFFFFF">
<one:PageSize>
<one:Automatic />
</one:PageSize>
<one:RuleLines visible="false" />
</one:PageSettings>
<one:Outline>
<one:Position x="36.0" y="32.39999771118164" z="0" />
<one:Size width="162.1652679443359" height="13.48873901367187" />
<one:OEChildren>
<one:OE alignment="left" quickStyleIndex="0">
<one:T><![CDATA[Lorem ipsum dolor sit amet]]></one:T>
</one:OE>
</one:OEChildren>
</one:Outline>
</one:Page>
To peek ahead just a little in discussion⦠what are we looking at above? The page is described by a containing one:Page element. The one:QuickStyleDef element describes the one style used on the page; note its index, 0. This is followed by a one:PageSettings element that describes the size and rule lines. And then there is a one:Outline that represents the first text "container" on the page. This container has one paragraph, a one:OE, which references quick style index 0. And that paragraph has one text run, a one:T. That text run has the string "Lorem ipsum dolor sit amet".
Styles
OneNote has a set of eleven standard built-in styles that can be applied to text on a page. These are listed in the Styles gallery in the Home ribbon tab
OneNote Styles |
How they appear on a page | |
|
|
These are static definitions, hard-coded in OneNote itself, and cannot be altered in any way. But let's explore how these are applied to text on a page. When a style is applied to text, OneNote will ensure that the style is defined in the XML by adding a corresponding one:QuickStyleDef element that describes that style.
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Exploration
Let's start with a simple example. If we were to add a Heading 1 line to this page:
This is a "Heading 1" line
OneNote first adds the following defintion if not already there. Note the value of the index attribute.
<one:QuickStyleDef index="2" name="h1" fontColor="#1E4E79" highlightColor="automatic" font="Calibri" fontSize="16.0" spaceBefore="0.0" spaceAfter="0.0" />
OneNote then links this style to a paragraph by applying its index value to the the quickStyleIndex attribute as shown here.
<one:OE alignment="left" quickStyleIndex="2">
<one:T><![CDATA[This is a "Heading 1" line]]></one:T>
</one:OE>
Now, what happens if we change the color of that heading using the Basic Text Font Color button on the ribbon?
This is a "Heading 1" line
This is the result in the XML
<one:OE alignment="left" quickStyleIndex="2"
style="font-family:Calibri;font-size:16.0pt;color:#C55A11">
<one:T><![CDATA[This is a "Heading 1" line]]></one:T>
</one:OE>
Notice that the quickStyleIndex is still set to "2" but a style attribute has been added. Also, this style attribute not only includes the color override (#C55A11) but also duplicates the font-family and font-size. It's unclear why Microsoft duplicates these properties in the style attribute; I do not know if it's stored this way in the binary format or it's just projected this way in the XML for clarity or convenience for consumers. But let's explore what happens if you change part of the line
This is a "Heading 1" line
This is the result in the XML
<one:OE alignment="left" quickStyleIndex="2">
<one:T><![CDATA[<span style='color:#C55A11'>This is a "</span><span style='color:#70AD47'>Heading 1</span><span style='color:#C55A11'>" line</span>]]></one:T>
</one:OE>
While the CDATA part appears to be a bit more complicated, we can easily break it down. CDATA contains a (very small) subset of HTML and CSS. In fact, that subset includes the span element and a limited set of styles that affect the font. So let's pull out the CDATA and look at it as if it were standalone XML.
<span style='color:#C55A11'>This is a "</span>
<span style='color:#70AD47'>Heading 1</span>
<span style='color:#C55A11'>" line</span>
The paragraph still has only one text run but that run is divided into separate spans. OneNote breaks it up to apply the explicit colors needed to override the implicit color of the Quick Style.
If we were to revert to the default color and then color only the "Heading 1" part, this is the result
This is a "<span style='color:#70AD47'>Heading 1</span>" line
So OneNote normalizes as much as it can, keeping only what's needed to express the desired result.
|
Now let's change the color of the entire line but italicize part of it.
This is a "Heading 1" line
Here's the XML
<one:OE alignment="left" quickStyleIndex="2"
style="font-family:Calibri;font-size:16.0pt;color:#C55A11">
<one:T><![CDATA[This is a "<span style='font-style:italic'>Heading 1</span>" line]]></one:T>
</one:OE>
Note that the font-family, font-size, and color are applied to the one:OE element, while font-style:italic is applied in a span in the CDATA.
|
Normalization and Promotion
As mentioned previously, OneNote does its best to normalize styles, promoting them upwards from a CDATA span to its parent OE - other than the noted rule exceptions above.
If you were to programmaticaly alter the XML or use the OneMore XML Dialog to alter the XML, you can add font family, size, and color to a CDATA span. When the page is saved, OneNote will normalize that, if it can, promoting those properties to the one:OE style attribute.
The Challenge of Complex Patterns
Consider this line of text
This line has multiple overlapping styles
Notice that there are overlapping styles, for example, the word "multiple" is styled two different ways: the first half is italic and highlighted, while the second half is italic and blue.
Its XML looks like this
<one:OE alignment="left" quickStyleIndex="1">
<one:T><![CDATA[This <span style='text-decoration:underline'>line </span><span style='text-decoration: underline;background:yellow;mso-highlight:yellow'>has </span><span style='font-style:italic;background:yellow;mso-highlight:yellow'>mu</span><span style='font-style:italic'>l</span><span style='font-style:italic;color:#5B9BD5'>tiple</span><span style='color:#5B9BD5'> over</span>lapping styles]]></one:T>
</one:OE>
Break down the CDATA into
This <span style='text-decoration:underline'>line </span>
<span style='text-decoration: underline;background:yellow;mso-highlight:yellow'>has </span>
<span style='font-style:italic;background:yellow;mso-highlight:yellow'>mu</span>
<span style='font-style:italic'>l</span><span style='font-style:italic;color:#5B9BD5'>tiple</span>
<span style='color:#5B9BD5'> over</span>lapping styles
This exemplifies the challenges of searching for the word "multiple" on the page, or applying custom styles to this paragraph.
Inconsistencies
There are times when OneNote loses its mind. While it certainly attempts to normalize as much as it can, it will, at unpredictable times, duplicate a Quick Style. While writing up this page, OneNote has added these duplicate definitions to the page.
<one:QuickStyleDef index="1" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.5" spaceBefore="0.0" spaceAfter="0.0" />
<one:QuickStyleDef index="11" name="p" fontColor="automatic" highlightColor="automatic" font="Calibri" fontSize="11.5" spaceBefore="0.0" spaceAfter="0.0" />
and
<one:QuickStyleDef index="2" name="h1" fontColor="#1E4E79" highlightColor="automatic" font="Calibri" fontSize="16.0" spaceBefore="0.0" spaceAfter="0.0" />
<one:QuickStyleDef index="12" name="h1" fontColor="#1E4E79" highlightColor="automatic" font="Calibri" fontSize="16.0" spaceBefore="0.0" spaceAfter="0.0" />
The definitions are the same, varying only by their index attributes. Why were they duplicated? Is this a bug? Who knows?
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
OneMore Styles
OneMore piggybacks on this basic OneNote style framework to implement the My Styles features. Since OneNote gracefully allows multiple Quick Style definitions with the same name, OneMore takes advantage of this to define its own styles.
When you create a new style, you can choose whether it is a paragraph style, a character style, or a heading. OneMore uses this information to generate an appropriate Quick Style definition.
When a new heading style is created and reordered, OneMore can use this information to generate a Quick Style with the appropriate h1..h6 name. By reusing the standard h1..h6 internal names, this makes it easy for OneMore to generate a table of contents for the page based on both standard headings and custom headings.
All other custom styles are represented by a new "p" Quick Style.
OneMore abides by the OneNote rules, attempting to apply and distribute styles in a normalized fashion, from CDATA to OE to QuickStyleDef.
However, there are times when OneMore does take advantage of the fact that OneNote will automatically normalize and reshuffle style properties when you save a page. So OneMore may dump styles into a span, even though they should go in the parent one:OE, knowing that OneNote will sort it out accordingly. These cases are rare but are often done to keep the OneMore code simple (or "simpler").
#omwiki #omdeveloper #omtechnote
Β© 2020 Steven M Cohn. All rights reserved.
Please consider a sponsorship or one-time donation to support ongoing development
Created with OneNote.